#ifndef Algebra_sgCPardiso_h
#define Algebra_sgCPardiso_h

#include "AlgebraModule.h"
#include "LinearSolver.h"

SG_NAMESPACE_OPEN

namespace Algebra
{
    /**
     * @brief Adapt Parallel Direct Sparse Solver for Clusters Interface.
     *
     * The Parallel Direct Sparse Solver for Clusters Interface solves large linear systems of equations
     * with sparse matrices on clusters..
     *
     * @see
     * https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-c/2025-0/parallel-direct-sp-solver-for-clusters-iface.html
     *
     * @author nene
     * @date February, 2025.
     */
    // Extend for the complex data type
    template <typename TDataType>
    struct CPardisoPrivate;

    template <typename TDataType>
    class ALGEBRA_EXPORT CPardiso : public TLinearSolver<TDataType>
    {
      public:
        ///@name Type Definitions
        ///@{
        typedef /*typename*/ TDataType                 DataType;
        typedef /*typename*/ Vector_t<TDataType>       VectorType;
        typedef /*typename*/ Matrix_t<TDataType>       MatrixType;
        typedef /*typename*/ SparseMatrix_t<TDataType> SparseMatrixType;
        ///@}

        CPardiso ();
        ~CPardiso () override;

        const char* getClassName () override;

        /// perform a numeric factorization of the given sparse matrix.
        /// @note KEEP THE MATRIX ALIVE DURING THE WHOLE SOLVING PROCESS.
        void compute (const SparseMatrixType& matrix) override;

        /// evaluate the solution x of Ax=b using the current decomposition of A.
        void solve (const VectorType& b, VectorType& x) const override;

        /// Computes the inverse of square matrix `b` (must be invertible) and stores it in `x` using direct solvers
        void slove (const SparseMatrixType& b, SparseMatrixType& x) const override;

        /// report whether previous computation was successful.
        Info_t info () const override;

      private:
        /// reset the solver state
        void init ();
        /// de-allocate the resouces for the factorization.
        void clearFactors ();

        // void checkMatrix ();

      private:
        bool m_factorizationIsOk = false;
        /// take Adapter Pattern to hide the underlying details.
        struct CPardisoPrivate<DataType>* d = nullptr;
    };

}  // namespace Algebra

SG_NAMESPACE_CLOSE

#endif  // Algebra_sgPardiso_h